package block

import (
	pow2 "Dome/pow"
	"Dome/tools"
	"bytes"
	"encoding/gob"
	"strconv"
	"time"
)

type Block struct {
	PrevHash []byte //上一个区块的哈希值
	TimeStamp int64 //时间戳
	Hash []byte //当前区块的哈希值
	Data []byte //交易信息
	Nonce int64 //随机数
}
/**
创建区块
 */
func NewBlock(data []byte,prevHash []byte)*Block{
	block := Block{
		PrevHash: prevHash,
		TimeStamp: time.Now().Unix(),
		Data: data,
	}
	pow := pow2.NewPow(block.Data,block.TimeStamp,block.PrevHash)
	hash,nonce := pow.Run()
	block.Hash = hash
	block.Nonce = nonce
	return &block
}
/*
	序列化：把结构体进行有序的排列
	把block转成[]byte
 */
//方法
func(block *Block)Serialize()([]byte,error){
	var result bytes.Buffer
	en := gob.NewEncoder(&result)
	err := en.Encode(block)
	if err != nil {
		return nil,err
	}
	return result.Bytes(),err
}
/*
	反序列化：把[]byte转回block
*/
//函数
func DeSerialize(data []byte)(*Block,error){
	reader := bytes.NewReader(data)
	de := gob.NewDecoder(reader)
	var block *Block
	err := de.Decode(&block)
	if err != nil{
		return nil, err
	}
	return block,nil
}

/**
计算区块的hash值
函数：谁都可以调用
方法：接收者/调用者 对应的人来用
当前区块的hash的计算方法：时间戳+上一个区块的hash值+交易信息
进行拼接 得到一个字符串
 */
func(block *Block)GetHash()[]byte{
	//把int转成[]byte 1.int转string  string转[]byte
	time := []byte(strconv.FormatInt(block.TimeStamp, 10))
	nonce := []byte(strconv.FormatInt(block.Nonce, 10))
	/**
	拼接 bytes.Join
	第一个参数 要拼接的内容
	第二个参数 以什么形式进行拼接
	*/
	hash := bytes.Join([][]byte{nonce,time,block.PrevHash,block.Data},[]byte{})
	return tools.SetHash(hash)
}
/**
创建创世区块
 */
func GenesisBlock(data []byte)*Block{
	return NewBlock(data,[]byte{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0})
}

